/*
 * main.c
 *
 *  Created on: May 3, 2011
 *      Author: tvale, dmourao
 */
#include "server.h"
#include "common.h"
#include "client.h"
#include <stdlib.h>
#include <mpi.h>
#include <stdio.h>

/*
 * Create custom MPI datatypes.
 */
static void
define_MPI_datatype_clock()
{
  int             blocklen[2] = { 1,       1           };
  MPI_Datatype    type[2]     = { MPI_INT, MPI_INT     };
  MPI_Aint        disp[2]     = { 0,       sizeof(int) };

  MPI_Type_create_struct(2, blocklen, disp, type, &MPI_CLOCK);
  MPI_Type_commit(&MPI_CLOCK);
}

static void
define_MPI_datatype_write()
{
  int             blocklen[2] = { 1,       1           };
  MPI_Datatype    type[2]     = { MPI_INT, MPI_CLOCK   };
  MPI_Aint        disp[2]     = { 0,       sizeof(int) };

  MPI_Type_create_struct(2, blocklen, disp, type, &MPI_WRITE);
  MPI_Type_commit(&MPI_WRITE);
}

static void
define_MPI_datatype_message()
{
  int             blocklen[2] = { 1,       1           };
  MPI_Datatype    type[2]     = { MPI_INT, MPI_WRITE   };
  MPI_Aint        disp[2]     = { 0,       sizeof(int) };

  MPI_Type_create_struct(2, blocklen, disp, type, &MPI_MESSAGE);
  MPI_Type_commit(&MPI_MESSAGE);
}



int
main(int argc, char* argv[])
{
  /* MPI init related */
  int myrank;
  int comm_size;
  int writes_per_client;

  MPI_Init(&argc, &argv);

  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  MPI_Comm_size(MPI_COMM_WORLD, &comm_size);

  /* Commit datatypes. */
  define_MPI_datatype_clock();
  define_MPI_datatype_write();
  define_MPI_datatype_message();

  writes_per_client = atoi(argv[1]);

  /* Rank 0, 2, 4, 6... servers */
  if (myrank % 2 == 0) {
    server_main(myrank, comm_size / 2);

    /* Rank 1, 3, 5, 7... clients */
  } else {
    client_main(myrank, writes_per_client);
  }

  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();

  return EXIT_SUCCESS;
}
